//
//  SwapController.swift
//  SCA
//
//  Created by tjun on 2025/9/7.
//

import UIKit
import SnapKit

class SwapFeeView: UIView {
    
    let feeLabel = UILabel(font: UIFontSemiboldMake(14), textColor: .white)
    let amountLabel = UILabel(font: UIFontSemiboldMake(13), textColor: .white)
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        feeLabel.addTo(self)
        feeLabel.snp.makeConstraints { make in
            make.left.equalToSuperview()
            make.centerY.equalToSuperview()
        }
        
        amountLabel.addTo(self)
        amountLabel.snp.makeConstraints { make in
            make.right.equalToSuperview()
            make.centerY.equalToSuperview()
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
}


class SwapFromView: UIView {
    
    var maxAmount: Float = 0
    let iconImageView = UIImageView()
    let iconNameLabel = UILabel(font: UIFontSemiboldMake(16), textColor: .white)
    let balanceLabel = UILabel(font: UIFontMake(13), textColor: .white)
    let quantityTextFiled = UITextField()
    let selectButton = UIButton(image: UIImage(named: "selectCoinArrow"))
    let totalAmountLabel = UILabel(text: "$ 0.00", font: UIFontMake(12), textColor: UIColorMake(0x919191))
    private let amountView = UIView()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        let titleLabel = UILabel(text: "转出代币".localizedString, font: UIFontMake(12), textColor: .white).addTo(self)
        titleLabel.snp.makeConstraints { make in
            make.left.equalTo(12)
            make.top.equalTo(10)
        }
        
        iconImageView.addTo(self)
        iconImageView.snp.makeConstraints { make in
            make.left.equalTo(12)
            make.centerY.equalToSuperview()
            make.width.height.equalTo(34)
        }
        
        iconNameLabel.addTo(self)
        iconNameLabel.numberOfLines = 2
        iconNameLabel.snp.makeConstraints { make in
            make.left.equalTo(iconImageView.snp.right).offset(10)
            make.centerY.equalTo(iconImageView)
            make.width.equalTo(100)
        }

        balanceLabel.addTo(self)
        balanceLabel.snp.makeConstraints { make in
            make.right.equalTo(-12)
            make.centerY.equalTo(titleLabel)
        }
        
        selectButton.addTo(self)
        selectButton.snp.makeConstraints { make in
            make.right.equalTo(self.snp.centerX).offset(-10)
            make.centerY.equalToSuperview()
            make.width.height.equalTo(35)
        }

        amountView.addTo(self)
        amountView.layer.borderColor = UIColorMake(0x646464).cgColor
        amountView.layer.borderWidth = 1
        amountView.layer.cornerRadius = 5
        amountView.snp.makeConstraints { make in
            make.right.equalTo(balanceLabel)
            make.centerY.equalToSuperview()
            make.width.equalTo(150)
            make.height.equalTo(32)
        }
        
        quantityTextFiled.addTo(amountView)
        quantityTextFiled.textColor = .white
        quantityTextFiled.delegate = self
        quantityTextFiled.textAlignment = .center
        quantityTextFiled.keyboardAppearance = .dark
        quantityTextFiled.keyboardType = .numberPad
        quantityTextFiled.clearButtonMode = .whileEditing
        quantityTextFiled.backgroundColor = UIColorMake(0x2E3036)
        quantityTextFiled.snp.makeConstraints { make in
            make.left.equalTo(5)
            make.right.equalToSuperview()
            make.top.bottom.equalToSuperview()
        }
        
        totalAmountLabel.addTo(self)
        totalAmountLabel.snp.makeConstraints { make in
            make.right.equalTo(balanceLabel)
            make.bottom.equalToSuperview().offset(-8)
        }
        
    }
    
    
    private func animateBorderColor(toColor: CGColor) {
        let animation = CABasicAnimation(keyPath: "borderColor")
        animation.fromValue = amountView.layer.borderColor
        animation.toValue = toColor
        animation.duration = 0.25  // 动画时长
        animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
        amountView.layer.add(animation, forKey: "borderColor")
        amountView.layer.borderColor = toColor
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
}

extension SwapFromView: UITextFieldDelegate {
    
    func textFieldDidBeginEditing(_ textField: UITextField) {
        animateBorderColor(toColor: UIColorMake(0x2078D5).cgColor)
    }

    func textFieldDidEndEditing(_ textField: UITextField) {
        animateBorderColor(toColor: UIColorMake(0x646464).cgColor)
    }
    
    func textField(_ textField: UITextField,
                   shouldChangeCharactersIn range: NSRange,
                   replacementString string: String) -> Bool {
        
        if string.isEmpty { return true }

        // 只允许数字
        guard string.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil else { return false }

        guard maxAmount >= 0 else { return false }

        // 拼接新字符串并检查最大金额
        if let oldText = textField.text as NSString? {
            let newText = oldText.replacingCharacters(in: range, with: string)
            if let value = Float(newText), value > maxAmount {
                DispatchQueue.main.async {
                    textField.text = "\(self.maxAmount)"
                }
                return false
            }
        }

        return true
    }
}


//extension SwapFromView: UITextFieldDelegate {
//
//
//    func textField(_ textField: UITextField,
//                   shouldChangeCharactersIn range: NSRange,
//                   replacementString string: String) -> Bool {
//
//        // 允许删除
//        if string.isEmpty { return true }
//
//        let currentText = textField.text ?? ""
//        let newText = (currentText as NSString).replacingCharacters(in: range, with: string)
//
//        // 第一位不能是小数点
//        if currentText.isEmpty && string == "." {
//            return false
//        }
//
//        // 只允许输入数字和小数点
//        let allowedCharacters = CharacterSet(charactersIn: "0123456789.")
//        if string.rangeOfCharacter(from: allowedCharacters.inverted) != nil {
//            return false
//        }
//
//        // 只允许一个小数点
//        let dotCount = newText.filter { $0 == "." }.count
//        if dotCount > 1 {
//            return false
//        }
//
//        // 限制小数点后最多两位
//        if let dotIndex = newText.firstIndex(of: ".") {
//            let decimalPart = newText[newText.index(after: dotIndex)...]
//            if decimalPart.count > 2 {
//                return false
//            }
//        }
//
//        return true
//    }
//}

class SwapToView: UIView {
    
    let iconImageView = UIImageView()
    let iconNameLabel = UILabel(font: UIFontSemiboldMake(16), textColor: .white)
    let balanceLabel = UILabel(font: UIFontMake(13), textColor: .white)
    let quantityLabel = UILabel(font: UIFontSemiboldMake(20), textColor: UIColor.white)
    let totalAmountLabel = UILabel(text: "0.00", font: UIFontMake(12), textColor: UIColorMake(0x919191))
    let selectButton = UIButton(image: UIImage(named: "selectCoinArrow"))
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        let titleLabel = UILabel(text: "至钱包".localizedString, font: UIFontMake(12), textColor: .white).addTo(self)
        titleLabel.snp.makeConstraints { make in
            make.left.equalTo(12)
            make.top.equalTo(10)
        }
        
        iconImageView.addTo(self)
        iconImageView.snp.makeConstraints { make in
            make.left.equalTo(12)
            make.centerY.equalToSuperview()
            make.width.height.equalTo(34)
        }
        
        iconNameLabel.addTo(self)
        iconNameLabel.numberOfLines = 2
        iconNameLabel.snp.makeConstraints { make in
            make.left.equalTo(iconImageView.snp.right).offset(10)
            make.centerY.equalTo(iconImageView)
            make.width.equalTo(100)
        }
        
        selectButton.addTo(self)
        selectButton.snp.makeConstraints { make in
            make.right.equalTo(self.snp.centerX).offset(-10)
            make.centerY.equalToSuperview()
            make.width.height.equalTo(35)
        }
        
        balanceLabel.addTo(self)
        balanceLabel.snp.makeConstraints { make in
            make.right.equalTo(-12)
            make.centerY.equalTo(titleLabel)
        }
        
        quantityLabel.addTo(self)
        quantityLabel.snp.makeConstraints { make in
            make.right.equalTo(balanceLabel)
            make.centerY.equalToSuperview()
        }
        
        totalAmountLabel.addTo(self)
        totalAmountLabel.snp.makeConstraints { make in
            make.right.equalTo(balanceLabel)
            make.bottom.equalToSuperview().offset(-10)
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
}

class SwapController: BaseController {
    
    var walletInfo: WalletInfo?
    private var scrollView: UIScrollView!
    private var contentView: UIView!
    
    private let fromView = SwapFromView()
    private let toView = SwapToView()
    private let feeView = SwapFeeView()
    
    private let passwordTextField = LabeledTextField()
    private let confirmButton = MainButton(type: .system, title: "确认".localizedString, font: UIFontMake(16), textColor: .white)
    private var swapData: SwapData?
    private var fromCoinModel: SwapCoinModel? {
        didSet {
            guard let coinModel = fromCoinModel else { return}
            
            fromView.iconImageView.setImage(url: coinModel.coinUrl)
            fromView.iconNameLabel.text = coinModel.coinName
            fromView.balanceLabel.text = coinModel.balanceDisp
            
            if let balance = coinModel.balance {
                fromView.maxAmount = Float(balance) ?? 0
            }
        }
    }
    
    private var toCoinModel: SwapCoinModel? {
        didSet {
            guard let coinModel = toCoinModel else { return}
            
            toView.iconImageView.setImage(url: coinModel.coinUrl)
            toView.iconNameLabel.text = coinModel.coinName
            toView.balanceLabel.text = coinModel.balanceDisp
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        navigationBar.title = "兑换".localizedString
        
        setupUI()
        loadData()
        
    }
    
    private func setupUI() {
        
        scrollView = UIScrollView(frame: CGRect(x: 0, y: navBarHeight, width: view.width, height: screenHeight - navBarHeight)).addTo(view)
        scrollView.keyboardDismissMode = .onDrag
        scrollView.showsVerticalScrollIndicator = false
        scrollView.showsHorizontalScrollIndicator = false
        scrollView.alwaysBounceVertical = true
        scrollView.contentInsetAdjustmentBehavior = .never
        
        let contentSize = CGSize(width: scrollView.width, height: scrollView.height)
        
        scrollView.contentSize = contentSize
        
        contentView = UIView().addTo(scrollView)
        contentView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
            make.size.equalTo(contentSize)
        }
        
        fromView.addCorner(radius: 10)
        fromView.addTo(contentView)
        fromView.selectButton.addTarget(self, action: #selector(fromViewSelectButtonTapped(_ :)), for: .touchUpInside)
        fromView.quantityTextFiled.addTarget(self, action: #selector(textFieldDidChange(_ :)), for: .editingChanged)
        fromView.backgroundColor = UIColorMake(0x2E323F)
        fromView.snp.makeConstraints { make in
            make.left.right.equalToSuperview().inset(AppStyle.margin.left)
            make.height.equalTo(94)
            make.top.equalTo(20)
        }
        
        let arrowImageView = UIImageView(image: UIImage(named: "swap_icon")).addTo(contentView)
        arrowImageView.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.top.equalTo(fromView.snp.bottom).offset(14)
        }
        
        toView.addCorner(radius: 10)
        toView.addTo(contentView)
        toView.selectButton.addTarget(self, action: #selector(toViewSelectButtonTapped(_ :)), for: .touchUpInside)
        toView.backgroundColor = UIColorMake(0x2E323F)
        toView.snp.makeConstraints { make in
            make.left.right.equalTo(fromView)
            make.height.equalTo(94)
            make.top.equalTo(arrowImageView.snp.bottom).offset(14)
        }
        
        feeView.addTo(contentView)
        feeView.alpha = 0
        feeView.snp.makeConstraints { make in
            make.top.equalTo(toView.snp.bottom)
            make.left.right.equalTo(fromView)
            make.height.equalTo(44)
        }
        
        passwordTextField.titleAttributedText = "二级安全密码*".localizedString.attributedString(rangeString: "*", rangeColor: UIColorMake(0xFF0000))
        contentView.addSubview(passwordTextField)
        passwordTextField.textField.keyboardType = .asciiCapable
        passwordTextField.textField.addTarget(self, action: #selector(textFieldDidChange(_ :)), for: .editingChanged)
        passwordTextField.snp.makeConstraints { make in
            make.top.equalTo(toView.snp.bottom).offset(10)
            make.left.right.equalTo(fromView)
            make.height.equalTo(74)
        }
        
        let attributedText = NSMutableAttributedString()
        attributedText.append(NSAttributedString(
            string: "免责声明请注意！\n".localizedString,
            attributes: [
                .foregroundColor: UIColor.white,
                .underlineStyle: NSUnderlineStyle.single.rawValue,
                .underlineColor: UIColor.white,
                .font: UIFontMake(16)
            ]
        ))
        attributedText.append(NSAttributedString(
            string: "兑换 USCA 不会额外获得 wSCA！".localizedString,
            attributes: [
                .foregroundColor: UIColor.white,
                .font: UIFontMake(16)
            ]
        ))
        
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = 3
        paragraphStyle.alignment = .left
        attributedText.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: attributedText.length))
        
        let hintLabel = UILabel().addTo(contentView)
        hintLabel.numberOfLines = 0
        hintLabel.attributedText = attributedText
        hintLabel.snp.makeConstraints { make in
            make.left.right.equalTo(fromView)
            make.top.equalTo(passwordTextField.snp.bottom).offset(16)
        }
        
        confirmButton.addTo(contentView)
        confirmButton.isEnabled = false
        confirmButton.addTarget(self, action: #selector(confirmButtonTapped), for: .touchUpInside)
        confirmButton.snp.makeConstraints { make in
            make.left.right.equalTo(fromView)
            make.height.equalTo(AppStyle.size.buttonHeight.scaled)
            make.top.equalTo(hintLabel.snp.bottom).offset(50)
        }
        
        updateContentSize()
    }
    
    @objc func textFieldDidChange(_ sender: UITextField) {
        if let quantity = fromView.quantityTextFiled.text,
           let password = passwordTextField.textField.text,
           (Float(quantity) ?? 0) > 0,
           password.count >= 6 {
            confirmButton.isEnabled = true
        } else {
            confirmButton.isEnabled = false
        }
        
        guard let fromModel = self.fromCoinModel,
              let toModel = self.toCoinModel,
              let fromDecimal = Int(fromModel.swapDecimal ?? "2"),
              let toDecimal = Int(toModel.swapDecimal ?? "2") else {
            return
        }
        
        if sender === fromView.quantityTextFiled {
            var inputText: String = "0.0"
            if let text = fromView.quantityTextFiled.text, !text.isEmpty {
                inputText = text
            }
            
            printf("inputText=\(inputText)")
            
            fromView.totalAmountLabel.text = "$" + inputText.formattedDecimal(decimals: fromDecimal)
            
            var outputText: String = "0.0"
            if let text = fromView.quantityTextFiled.text,
                !text.isEmpty,
                let swapData = self.swapData,
                let toMultiplier = swapData.multiplier[fromModel.coin] as? [String: Any] {
                
                let multiplier = toMultiplier.stringValue(toModel.coin)
                outputText = text.multiply(multiplier)
            }
            
            toView.totalAmountLabel.text = "$" + outputText.formattedDecimal(decimals: toDecimal)
            toView.quantityLabel.text =  outputText.formattedDecimal(decimals: toDecimal)
            
            var feeOutputText: String = "0.0"
            if let text = fromView.quantityTextFiled.text, !text.isEmpty, let fee = toModel.fee {
                feeOutputText = text.multiply(fee)
            }
            feeView.amountLabel.text = feeOutputText.formattedDecimal(decimals: toDecimal)
        }
    }
    
    @objc func confirmButtonTapped() {
        guard let amount = fromView.quantityTextFiled.text,
           let password = passwordTextField.textField.text,
              let fromCoin = self.fromCoinModel?.coin,
              let toCoin = self.toCoinModel?.coin,
              let fromCoinName = self.fromCoinModel?.coinName,
              let toCoinName = self.toCoinModel?.coinName
        else {
            return
        }
        
        
        HUD.showLoadingInView(self.view)
        WalletService.swap(fromCoin: fromCoin, toCoin: toCoin, amount: amount, pinCode: password) {swapAmount, error in
            HUD.hideHUD(for: self.view)
            if error == nil, let swap_amount = swapAmount {
//                兑换成功！您已成功兑换了 USDT 为 1.00 USCA。
                let transactionSuccessController = TransactionSuccessController(text: String(format:  "兑换成功! 您已成功兑换了 %@  为 %@ %@".localizedString, fromCoinName, swap_amount, toCoinName))
                self.navigationController?.pushViewController(transactionSuccessController, animated: true)
                self.navigationController?.viewControllers = self.removeNavChildViewControllers(["SwapController"])
                NotificationCenter.default.post(name: NotificationName.swapSuccess, object: nil)
            } else {
                HUD.showErrorMessage(error)
            }
        }
        
    }
    
    @objc func fromViewSelectButtonTapped(_ button: UIButton) {
        guard let data = self.swapData else {
            return
        }
        let fromViewFrame = button.convert(button.bounds, to: UIApplication.shared.windows.first { $0.isKeyWindow })
        let selectCoinController = SwapSelectCoinController(datas: data.fromList)
        selectCoinController.fromRect = CGRectMake(ceil(fromViewFrame.origin.x), ceil(fromViewFrame.origin.y), fromViewFrame.width, fromViewFrame.height)
        selectCoinController.onSelectCoin = { model in
            self.fromCoinModel = model
            let subCoinModels = model.subCoinModels
            subCoinModels.forEach { $0.isSelected = false }
            self.toCoinModel = model.subCoinModels.first
            self.toCoinModel?.isSelected = true
            
            self.fromView.quantityTextFiled.text = nil
            self.textFieldDidChange(self.fromView.quantityTextFiled)
            
            DispatchQueue.main.async {
                self.isNeedFree()
            }

        }
        present(selectCoinController, animated: false)
    }
    
    @objc func toViewSelectButtonTapped(_ button: UIButton) {
        
        guard let fromCoinModel = self.fromCoinModel else {
            return
        }
        
        let fromViewFrame = button.convert(button.bounds, to: UIApplication.shared.windows.first { $0.isKeyWindow })
        let selectCoinController = SwapSelectCoinController(datas: fromCoinModel.subCoinModels)
        selectCoinController.fromRect = CGRectMake(ceil(fromViewFrame.origin.x), ceil(fromViewFrame.origin.y), fromViewFrame.width, fromViewFrame.height)
        selectCoinController.onSelectCoin = { model in
            self.toCoinModel = model
            DispatchQueue.main.async {
                self.isNeedFree()
            }
            
            //根据金额刷新
            self.textFieldDidChange(self.fromView.quantityTextFiled)
            
        }
        present(selectCoinController, animated: false)
    }
    
    var isShowFree: Bool = false
    
    func isNeedFree() {
        guard let fromCoinModel = self.fromCoinModel,
              let toCoinModel = self.toCoinModel else {
            return
        }
        
        if let fromCoinFee = fromCoinModel.fee,
            let toCoinFee = toCoinModel.fee,
            let toCoinFeeDisp = toCoinModel.feeDisp,
            let fromCoinFeeValue = Float(fromCoinFee), fromCoinFeeValue > 0,
            let toCoinFeeValue = Float(toCoinFee), toCoinFeeValue > 0,
            let toDecimal = Int(toCoinModel.swapDecimal ?? "2") {
            
            var inputText: String = "0.0"
            if let text = fromView.quantityTextFiled.text, !text.isEmpty {
                inputText = text
            }
            self.isShowFree = true
            self.feeView.feeLabel.text = String(format: "熔炉基金 %@".localizedString, toCoinFeeDisp)
            self.feeView.amountLabel.text = inputText.formattedDecimal(decimals: toDecimal)
            UIView.animate(withDuration: 0.25) {
                self.feeView.alpha = 1
                self.passwordTextField.snp.remakeConstraints { make in
                    make.top.equalTo(self.feeView.snp.bottom)
                    make.left.right.equalTo(self.fromView)
                    make.height.equalTo(74)
                }
                self.contentView?.layoutIfNeeded()
            } completion: { _ in
                self.updateContentSize()
            }
        } else {
            self.isShowFree = false
            UIView.animate(withDuration: 0.25) {
                self.feeView.alpha = 0
                self.passwordTextField.snp.remakeConstraints { make in
                    make.top.equalTo(self.toView.snp.bottom).offset(10)
                    make.left.right.equalTo(self.fromView)
                    make.height.equalTo(74)
                }
                self.contentView?.layoutIfNeeded()
            } completion: { _ in
                self.updateContentSize()
            }
        }
    }
    
    private func updateContentSize() {
        
        contentView.setNeedsLayout()
        contentView.layoutIfNeeded()
        
        let contentSize = CGSizeMake(view.width, confirmButton.maxY + 10 + tabBarSafeBottomMargin)
        scrollView.contentSize = contentSize
        contentView.snp.remakeConstraints { make in
            make.edges.equalToSuperview()
            make.size.equalTo(contentSize)
        }
    }
    
    func loadData() {
        WalletService.loadSwapData { data, error in
            guard let swapData = data, let coinModels = self.walletInfo?.coinModels else {
                return
            }
            
            let coinModelDict = Dictionary(uniqueKeysWithValues: coinModels.map { ($0.coin, $0) })
            for fromSwapModel in swapData.fromList {
                
                if let match = coinModelDict[fromSwapModel.coin] {
                    fromSwapModel.coinUrl = match.coinUrl
                }
                
                if fromSwapModel.coin == swapData.defaultFrom.lowercased() {
                    self.fromCoinModel = fromSwapModel
                    self.fromCoinModel?.isSelected = true
                }
                
                for toSwapModel in fromSwapModel.subCoinModels {
                    if let match = coinModelDict[toSwapModel.coin] {
                        toSwapModel.coinUrl = match.coinUrl
                    }
                    
                    if toSwapModel.coin == swapData.defaultTo.lowercased() {
                        self.toCoinModel = toSwapModel
                        self.toCoinModel?.isSelected = true
                    }
                }
            }
            self.swapData = swapData
        }
    }
    
}
